使用Inno Setup打包windows程序

开发windows程序完成后,将执行文件目录进行压缩打包就可以给其他人用了。但是这样是不是略显low呢?
那么将我们的执行目录进行打包成安装程序并带上图标是不是立马高大上起来了!一般windows下有不同后缀的安装包,如exe,msi等,可以通过不同的打包脚本完成打包。
本文是通过Inno Setup Script打包安装的一个详尽例子,基本满足大部分需求。

以下是一个打包脚本的示例,涵盖了基本的需求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
; Script generated by the Inno Script Studio Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "应用程序名称"
#define MyAppVersion "版本号"
#define MyAppPublisher "发布机构"
#define MyAppURL "网址"
#define MyAppExeName "程序名"
#define MyAppTimeString GetDateTimeString('yyyymmdd-hhnnss',':',':')

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId=程序Guids
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={userappdata}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=no
OutputDir=安装包生成目录
OutputBaseFilename=安装包名称
SetupIconFile=图标路径
Compression=lzma
SolidCompression=yes
CloseApplications=force
DisableDirPage=no
DisableWelcomePage=no
VersionInfoVersion={#MyAppVersion}
VersionInfoCompany=公司名称
ShowLanguageDialog=auto
LanguageDetectionMethod=locale;根据本地语言加载

[Languages]
Name: "us_en"; MessagesFile: "./Language/us_en.isl"
Name: "zh_cn"; MessagesFile: "./Language/zh_cn.isl"

;安装组件选择
[Components]
Name: main; Description:"主程序(必选)";Types:full compact custom;Flags: fixed
Name: part1; Description:"组件1";Types:full
Name: part2; Description:"组件2";Types:full

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkablealone

;修改ini
[Ini]
Filename: "{app}\config\RunInfo.ini"; Section: "System"; Key: "Version"; String: "{#MyAppVersion}"

;安装包文件
[Files]
Source: "{#MyAppPath}\xxx.exe"; DestDir: "{app}"; Flags: ignoreversion;Components:main
Source: "{#MyAppPath}\组件1.exe"; DestDir: "{app}"; Flags: ignoreversion;Components:part1
Source: "{#MyAppPath}\组件2.exe"; DestDir: "{app}"; Flags: ignoreversion;Components:part2
Source: psvince.dll; DestDir: {app}

[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"; Flags: uninsneveruninstall
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

[InstallDelete]
Type: filesandordirs; Name: "{app}\*"

[UninstallDelete]
Type: filesandordirs; Name: "{app}\*"

[Code]
// function IsModuleLoaded to call at install time
// added also setuponly flag
function IsModuleLoaded(modulename: String ): Boolean;
external 'IsModuleLoaded@files:psvince.dll stdcall setuponly';

// function IsModuleLoadedU to call at uninstall time
// added also uninstallonly flag
function IsModuleLoadedU(modulename: String ): Boolean;
external 'IsModuleLoaded@{app}\psvince.dll stdcall uninstallonly' ;

;判断进程是否存在
function IsAppRunning(const FileName : string): Boolean;
var
FSWbemLocator: Variant;
FWMIService : Variant;
FWbemObjectSet: Variant;
begin
Result := false;
try
FSWbemLocator := CreateOleObject('WBEMScripting.SWBEMLocator');
FWMIService := FSWbemLocator.ConnectServer('', 'root\CIMV2', '', '');
FWbemObjectSet := FWMIService.ExecQuery(Format('SELECT Name FROM Win32_Process Where Name="%s"',[FileName]));
Result := (FWbemObjectSet.Count > 0);
FWbemObjectSet := Unassigned;
FWMIService := Unassigned;
FSWbemLocator := Unassigned;
except
if (IsModuleLoaded(FileName)) then
begin
Result := false;
end
else
begin
Result := true;
end
end;
end;

;通过名称终结进程
procedure TaskKillProcessByName(AppName: String);
var
WbemLocator : Variant;
WMIService : Variant;
WbemObjectSet: Variant;
WbemObject : Variant;
begin;
WbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
WMIService := WbemLocator.ConnectServer('localhost', 'root\CIMV2');
WbemObjectSet := WMIService.ExecQuery('SELECT * FROM Win32_Process Where Name="' + AppName + '"');
if not VarIsNull(WbemObjectSet) and (WbemObjectSet.Count > 0) then
begin
WbemObject := WbemObjectSet.ItemIndex(0);
if not VarIsNull(WbemObject) then
begin
WbemObject.Terminate();
WbemObject := Unassigned;
end;
end;
end;

;安装的时候判断进程是否存在,存在则先提示是否结束进程
function InitializeSetup(): Boolean;
begin
Result := true;
if IsAppRunning('{#MyAppExeName}') then
begin
if MsgBox('安装程序检测到 {#MyAppName} 正在运行!'#13''#13'单击“是”按钮关闭程序并继续安装;'#13''#13'单击“否”按钮退出安装!', mbConfirmation, MB_YESNO) = IDYES then
begin
TaskKillProcessByName('{#MyAppExeName}');
TaskKillProcessByName('{#MyAppExeName}');
Result:= true;
end
else
Result:= false;
end;
end;

;卸载的时候判断进程是否存在,存在则先提示是否结束进程
function InitializeUninstall(): Boolean;
begin
Result:= true;
if IsAppRunning('{#MyAppExeName}') then
begin
if MsgBox('卸载程序检测到 {#MyAppName} 正在运行!'#13''#13'单击“是”按钮关闭程序并继续卸载;'#13''#13'单击“否”按钮退出卸载!', mbConfirmation, MB_YESNO) = IDYES then
begin
TaskKillProcessByName('{#MyAppExeName}');
TaskKillProcessByName('{#MyAppExeName}');
Result:= true;
end
else
Result:= false;
end;
// Unload the DLL, otherwise the dll psvince is not deleted
UnloadDLL(ExpandConstant('{app}\psvince.dll'));
DelTree(ExpandConstant('{app}'), True, True, True);
end;

lasyman wechat
-------------本文结束感谢您的阅读-------------